package com.cxf.windex.rest;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.cxf.windex.base.constant.UserConstant;
import com.cxf.windex.base.msg.ObjectRestResponse;
import com.cxf.windex.base.msg.TableResultResponse;
import com.cxf.windex.base.rest.BaseRestController;
import com.cxf.windex.base.util.EncryptUtil;
import com.cxf.windex.base.util.IdUtil;
import com.cxf.windex.base.util.NumUtil;
import com.cxf.windex.base.util.QRUtil;
import com.cxf.windex.base.util.ShorUrlUtil;
import com.cxf.windex.base.util.SmsDemo;
import com.cxf.windex.base.util.WxUtil;
import com.cxf.windex.base.vo.UserTree;
import com.cxf.windex.biz.CxfUserBiz;
import com.cxf.windex.entity.CxfPlatform;
import com.cxf.windex.entity.CxfUser;
import com.cxf.windex.entity.PlatformUser;
import com.cxf.windex.task.RegisterTask;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.LocalDateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

/**
 * @author chenxf
 * @date 3/8/2018
 * @description
 */
@Api(tags = {"聚能小宝 - 用户接口"})
@Controller
@RequestMapping("user")
public class CxfUserController extends
    BaseRestController<CxfUserBiz, CxfUser> {

  @Value("${sms.accessKeyId}")
  private String accessKeyId;

  @Value("${sms.accessKeySecret}")
  private String accessKeySecret;

  @Value("${sms.signName}")
  private String signName;

  @Value("${sms.templateCode}")
  private String templateCode;

  /**
   * 文件存放 路径
   */
  @Value("${upload.path}")
  private String uploadPath;

  /**
   * 文件访问路径
   */
  @Value("${upload.url}")
  private String uploadUrl;

  /**
   * 文件访问域名
   */
  @Value("${upload.uri}")
  private String uploadUri;

  /**
   * 二维码地址
   */
  @Value("${upload.qrUrl}")
  private String qrUrl;

  /**
   * 小宝控制首页
   */
  @Value("${upload.qrIndexUrl}")
  private String qrIndexUrl;

  /**
   * 二维码logo
   */
  @Value("${upload.qrLogo}")
  private String qrLogo;

  @Value("${weixin.appid}")
  private String appid;

  @Autowired
  private CacheManager cacheManager;

  private String cacheName = "smsCode";

  @Autowired
  private RegisterTask registerTask;



  @ApiOperation(value = "获取销售用户列表", notes = "获取销售用户列表")
  @RequestMapping(value = "/list", method = RequestMethod.GET)
  @ResponseBody
  public TableResultResponse<CxfUser> getInfo(@RequestParam(defaultValue = "10") int limit,
      @RequestParam(defaultValue = "1") int offset,
      @RequestParam(defaultValue = "desc") String orderStr, String name, String phone) {
    Example example = new Example(CxfUser.class);
    Example.Criteria criteria = example.createCriteria();
    String type = this.getCurrentUserType();
    if (!type.equals("4")) {
      criteria.andEqualTo("crtUser", this.getCurrentUserId());
    }
    if (StringUtils.isNotBlank(name)) {
      criteria.andLike("name", "%" + name + "%");
    }
    if (StringUtils.isNotBlank(phone)) {
      criteria.andLike("username", "%" + phone + "%");
    }
    example.setOrderByClause("crt_time  desc");
    PageHelper.startPage(offset, limit);
    List<CxfUser> items = baseBiz.selectByExample(example);

    PageInfo<CxfUser> pageInfo = new PageInfo<CxfUser>(items);
    return new TableResultResponse<CxfUser>(Integer.parseInt(String.valueOf(pageInfo.getTotal())),
        offset, limit,
        items);
  }


  @ApiOperation(value = "分销用户", notes = "获取分销下线用户 ")
  @RequestMapping(value = "/hy", method = RequestMethod.GET)
  @ResponseBody
  public List<UserTree> hy() {
    String userId = this.getCurrentUserId();
    if (userId == null || StringUtils.isBlank(userId)) {
      return new ArrayList<UserTree>();
    }
    List<UserTree> userTreeList = baseBiz.selectHy(userId, UserConstant.MAXTIMES);
    return userTreeList;
    //getMenuTree(userTreeList,Long.parseLong(userId));
  }

  @ApiOperation(value = "登陆", notes = "登陆返回TOKEN")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "username", value = "用户名", required = true, paramType = "query", dataType = "String"),
      @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query", dataType = "String")
  })
  @RequestMapping(value = "/login", method = RequestMethod.POST)
  @ResponseBody
  public ObjectRestResponse login(String username, String password) {
    CxfUser queryEntity = new CxfUser();
    queryEntity.setUsername(username);

    CxfUser user = baseBiz.selectOne(queryEntity);
    if (user == null) {
      return new ObjectRestResponse().rel(false).msg("用户不存在");
    }
    if (!EncryptUtil.decrypt(user.getPassword()).equals(password)) {
      return new ObjectRestResponse().rel(false).msg("密码不正确");
    }
    resultMap.put("token", this.setCurrentUserName(user));

    return new ObjectRestResponse().rel(true).msg("登陆成功").result(resultMap);
  }

  @ApiOperation(value = "获取用户信息", notes = "获取用户信息")
  @RequestMapping(value = "/userInfo", method = RequestMethod.GET)
  @ResponseBody
  public ObjectRestResponse getUserInfo() {
    String userid = this.getCurrentUserId();
    if (StringUtils.isBlank(userid)) {
      return new ObjectRestResponse().rel(false).msg("用户未登陆");
    }
    CxfUser cxfUser = baseBiz.selectById(userid);
    if (cxfUser == null) {
      return new ObjectRestResponse().rel(false).msg("用户不存在");
    }
    return new ObjectRestResponse().rel(true).msg("查询成功").result(cxfUser);
  }

  @ApiOperation(value = "获取小宝推广码", notes = "获取小宝推广码")
  @RequestMapping(value = "/code", method = RequestMethod.GET)
  @ResponseBody
  public ObjectRestResponse getCode() {
    String userid = this.getCurrentUserId();
    if (StringUtils.isBlank(userid)) {
      return new ObjectRestResponse().rel(false).msg("用户未登陆");
    }
    CxfUser cxfUser = baseBiz.selectById(userid);
    if (cxfUser == null) {
      return new ObjectRestResponse().rel(false).msg("用户不存在");
    }
    String qrCode = this.saveMinaCode(userid, cxfUser.getCrtName(), UserConstant.XB_CODEPREX);
    if (StringUtils.isBlank(qrCode)) {
      return new ObjectRestResponse().rel(false).msg("推广码生成失败");
    }
    resultMap.put("qrCode", qrCode);
    resultMap.put("crtName", cxfUser.getCrtName());
    return new ObjectRestResponse().rel(true).msg("查询成功").result(resultMap);
  }

  @ApiOperation(value = "获取小宝推广码跳转链接", notes = "获取小宝推广码跳转链接")
  @RequestMapping(value = "/codeUrl/{crtName}",  method = RequestMethod.GET)
  public void codeUrl(HttpServletResponse response, @PathVariable String crtName,String code) {
    String indexUrl = qrIndexUrl .replace("NAME",crtName).replace("CODE",code);
    //
    try {
      response.sendRedirect(indexUrl);
    } catch (IOException e) {
      e.printStackTrace();
    }
    return;
  }


  @ApiOperation(value = "注册", notes = "注册返回TOKEN")
  @RequestMapping(value = "/register", method = RequestMethod.POST)
  @ResponseBody
  public ObjectRestResponse register(CxfUser entity) {
    String phone = entity.getUsername();
    LocalDateTime sendTime =
        cacheManager.getCache(cacheName).get(phone + "Date", LocalDateTime.class);
    if (sendTime != null) {
      if (sendTime.plusSeconds(600).isBefore(LocalDateTime.now())) {
        return new ObjectRestResponse().rel(false).msg("验证码已超时");
      }
    }
    String veryCode = cacheManager.getCache(cacheName).get(phone, String.class);
    if (veryCode == null || !veryCode.equals(entity.getCode())) {
      return new ObjectRestResponse().rel(false).msg("验证码错误");
    }
    CxfUser queryEntity = new CxfUser();
    queryEntity.setUsername(entity.getUsername());

    CxfUser user = baseBiz.selectOne(queryEntity);
    if (user != null) {
      user.setWxopenid(entity.getWxopenid());
      user.setName(entity.getName());
      user.setImgUrl(entity.getImgUrl());
      resultMap.put("token", this.setCurrentUserName(user));

      return new ObjectRestResponse().rel(true).msg("绑定成功").result(resultMap);
    }
    if (StringUtils.isBlank(entity.getUsername()) || StringUtils.isBlank(entity.getPassword())
        || StringUtils.isBlank(entity.getName())) {
      return new ObjectRestResponse().rel(false).msg("手机号、密码、昵称不能为空");
    }
    if (StringUtils.isNotBlank(entity.getCrtName())) {
      queryEntity = new CxfUser();
      queryEntity.setCrtName(entity.getCrtName());
      user = baseBiz.selectOne(queryEntity);
      if (user != null) {
        entity.setCrtUser(user.getId());
      } else {
        logger.error("推广码={} 找不到对应用户", entity.getCrtName());
      }
    }
    entity.setPassword(EncryptUtil.encrypt(entity.getPassword()));
    entity.setId(new IdUtil(5, 1).nextId() + "");
    entity.setStatus("0");
    entity.setType("0");
    entity.setSex(NumUtil.randomInt(2) + "");

    entity.setCrtName(ShorUrlUtil.shortUrl(entity.getId())[0]);
    Map<String, Object> resultMap = new HashMap<String, Object>(4);
    baseBiz.insert(entity);
    registerTask.doRegisterTask(entity);
    resultMap.put("token", this.setCurrentUserName(entity));

    return new ObjectRestResponse().rel(true).msg("绑定成功").result(resultMap);
  }


  @ApiOperation(value = "修改密码", notes = "通过旧密码修改密码")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query", dataType = "String"),
      @ApiImplicitParam(name = "newPassword", value = "新密码", required = true, paramType = "query", dataType = "String"),
      @ApiImplicitParam(name = "newPassword2", value = "新密码2", required = true, paramType = "query", dataType = "String")
  })
  @RequestMapping(value = "/pwd", method = RequestMethod.POST)
  @ResponseBody
  public ObjectRestResponse pwd(String password, String newPassword, String newPassword2) {
    if (StringUtils.isBlank(password)) {
      return new ObjectRestResponse().rel(false).msg("密码不能为空");
    }

    if (StringUtils.isBlank(newPassword)) {
      return new ObjectRestResponse().rel(false).msg("新密码不能为空");
    }

    if (StringUtils.isBlank(newPassword2)) {
      return new ObjectRestResponse().rel(false).msg("重复新密码不能为空");
    }

    if (!newPassword.equals(newPassword2)) {
      return new ObjectRestResponse().rel(false).msg("重复新密码与新密码不相同");
    }
    String userId = this.getCurrentUserId();
    if (StringUtils.isBlank(userId)) {
      return new ObjectRestResponse().rel(false).msg("当前用户不存在");
    }

    CxfUser user = baseBiz.selectById(userId);
    if (user == null) {
      return new ObjectRestResponse().rel(false).msg("用户不存在");
    }
    if (!EncryptUtil.decrypt(user.getPassword()).equals(password)) {
      return new ObjectRestResponse().rel(false).msg("密码不正确");
    }
    CxfUser pwduser = new CxfUser();
    pwduser.setId(user.getId());
    pwduser.setPassword(EncryptUtil.encrypt(newPassword));
    baseBiz.updateSelectiveById(pwduser);
    return new ObjectRestResponse().rel(true).msg("修改成功");
  }

  @ApiOperation(value = "发送短信验证码", notes = "发送短信验证码")
  @RequestMapping(value = "/sendText", method = RequestMethod.GET)
  @ResponseBody
  public ObjectRestResponse sendText(String phone) throws IOException {
    if (StringUtils.isBlank(phone)) {

      return new ObjectRestResponse().rel(false).msg("请输入手机号码");
    }

    if (!validate(phone)) {
      return new ObjectRestResponse().rel(false).msg("一分钟内只能发送一次验证码");
    }
    // 手机验证码改成4位
    String veryCode = RandomStringUtils.randomNumeric(4);

    // 验证码放入缓存
    cacheManager.getCache(cacheName).put(phone,
        veryCode);
    cacheManager.getCache(cacheName).put(
        phone + "Date", LocalDateTime.now());
    logger.info("veryCode:" + veryCode);
    // 发送验证码
    try {
      SendSmsResponse response = SmsDemo
          .sendSms(phone, signName, templateCode, veryCode, accessKeyId, accessKeySecret);
      logger.debug("result={}", response.getMessage());
      if(!"OK".equals(response.getMessage())){
        return new ObjectRestResponse().rel(false).msg("发送失败:"+response.getMessage());
      }
    } catch (ClientException e) {
      logger.error(e.getErrMsg());
    }

    return new ObjectRestResponse().rel(true).msg("发送成功");

  }

  /**
   * 1分钟内 同一手机号 同一应用只发送一次短信验证码
   *
   * @param phone 手机号
   */
  private boolean validate(String phone) {

    LocalDateTime sendTime =
        cacheManager.getCache(cacheName).get(phone + "Date", LocalDateTime.class);
    if (sendTime != null) {
      if (sendTime.plusSeconds(60).isAfter(LocalDateTime.now())) {
        return false;
      }
    }
    return true;

  }

  private String saveMinaCode(String userId, String crtName, String prex) {
    String webRoot =
        uploadPath + File.separator + "weixin" + File.separator;
    String saveUrl =
        uploadUri + uploadUrl + "/weixin/" + prex + userId + ".jpg";
    File directoryFile = new File(webRoot);
    if (!directoryFile.exists()) {
      directoryFile.mkdirs();
    }
    String codePath = webRoot + userId + ".jpg";
    File codeFile = new File(codePath);
    if (codeFile.exists()) {
      return saveUrl;
    }
    Path path = Paths.get(webRoot + userId + ".jpg");
    String newWeixinUrl=WxUtil.getGZHUrl(appid, qrUrl.replace("NAME",crtName));

    QRUtil.saveQrCode(codePath, uploadPath + File.separator + qrLogo, newWeixinUrl, 300, 300,
        prex);

    return saveUrl;
  }

}
